/*
 * Copyright (C) 2009, Edmundo Albuquerque de Souza e Silva.
 *
 * This file may be distributed under the terms of the Q Public License
 * as defined by Trolltech AS of Norway and appearing in the file
 * LICENSE.QPL included in the packaging of this file.
 *
 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

package net.sf.fmj.media;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

import javax.media.Buffer;
import javax.media.Track;

import net.sf.fmj.utility.LoggerSingleton;

/**
 * Implements InputStream by wrapping a Track.
 * 
 *
 */
public class TrackInputStream extends InputStream
{
	private static final Logger logger = LoggerSingleton.logger;

	private final Track track;
	private Buffer buffer;
	
	public TrackInputStream(Track track)
	{
		super();
		this.track = track;
	}

	public Buffer getBuffer()
	{	return buffer;
	}
	
	private void fillBuffer()
	{
		if (buffer == null)
		{	
			buffer = new Buffer();
			buffer.setFormat(track.getFormat());
			
		}
		
		
		do
		{
			if (buffer.isEOM())
				return;
			
			if (buffer.getLength() > 0)
				return;	 // still have data in buffer
			// TODO: any fields to set?

			track.readFrame(buffer);
			logger.fine("Read buffer from track: " + buffer.getLength());
			
		}
		while (buffer.isDiscard());
	}
	
	//@Override
	public int read() throws IOException
	{
		// TODO: how do we detect IOException? 
		fillBuffer();
		if (buffer.getLength() == 0 && buffer.isEOM()) // TODO: will always be EOM if length is 0
			return -1;
		final byte[] data = (byte[]) buffer.getData();
		final int result = data[buffer.getOffset()] & 0xff;
		buffer.setOffset(buffer.getOffset() + 1);
		buffer.setLength(buffer.getLength() - 1);
		
		return result;
		
	}

	//@Override
	public int read(byte[] b, int off, int len) throws IOException
	{
		
		// TODO: how do we detect IOException? 
		fillBuffer();
		if (buffer.getLength() == 0 && buffer.isEOM()) // TODO: will always be EOM if length is 0
			return -1;
		final byte[] data = (byte[]) buffer.getData();

		int lengthToCopy = buffer.getLength() < len ? buffer.getLength() : len;
		System.arraycopy(data, buffer.getOffset(), b, off, lengthToCopy);
		buffer.setOffset(buffer.getOffset() + lengthToCopy);
		buffer.setLength(buffer.getLength() - lengthToCopy);

		return lengthToCopy;
	}


}
